Components.utils.import("resource:///modules/MailUtils.js");

var folderplus = {
	
	
	// ============================================================================================================
	//   Commands, events
	// ============================================================================================================
	
	/**
	 * Go to folder of current message Always use the first tab of type "Folder"
	 * Don't use a tab as gloda search Change folder even if message already
	 * visible in a virtual folder.
	 */
	goToFolder : function() {
		var aMsgHdr = gFolderDisplay.selectedMessage;
		var folder = gFolderTreeView.getFolderForMsgHdr(aMsgHdr);
		this._GoToFolder(folder, aMsgHdr);
	},

	/**
	 * Same as goToFolder. Maybe it will be changed in future :-/
	 */
	goToThread : function() {
		folderplus.log("folderDisplay.goToThread");
		var aMsgHdr = gFolderDisplay.selectedMessage;
		function callback(aFolderURI){
			folderplus.log("goToThread.callback" + aFolderURI);
			if (aFolderURI && aFolderURI != "error") {
				var folder = MailUtils.getFolderForURI(aFolderURI);
				// On transmet pas de message pour ne sélectionner pas de message.
				if (folder) {
					folderplus._GoToFolder(folder, aMsgHdr);
				}
			}
		};
		folderplus.conv._getFolder(aMsgHdr, callback, Gloda, folderplus.callbackUI);
	},
	
	goToLastMoved : function () {
    folderplus.log("folderDisplay.goToLastMoved");
    var folderId = Services.prefs.getCharPref("mail.last_msg_movecopy_target_uri");
		var folder = MailUtils.getFolderForURI(folderId, false)
		this._GoToFolder(folder, null);
	},

	goToInbox : function () {
		folderplus.log("folderDisplay.goToInbox");
		var defaultAccountRootFolder = GetDefaultAccountRootFolder();

		// if no default account, get msg isn't going do anything anyways
		// so bail out
		if (!defaultAccountRootFolder)
			return;
		
		var inboxFolder = defaultAccountRootFolder.getFolderWithFlags(Components.interfaces.nsMsgFolderFlags.Inbox);
		
		if (!inboxFolder)
			return;
		
		this._GoToFolder(inboxFolder, null);
	},

	/**
	 * Go to folder of current message Always use the first tab of type "Folder"
	 * Don't use a tab as gloda search Change folder even if message already
	 * visible in a virtual folder.
	 */
	_GoToFolder : function(folder, aMessage) {
		folderplus.log("folderDisplay._GoToFolder");
		folderplus.log("folder = " + folder);
		// inspired from MsgDisplayMessageInFolderTab
		// but force using first tab to manage virdual folder.
		var tabmail = document.getElementById("tabmail");
		var folderTabs = tabmail.tabModes["folder"];
		var folderTab = folderTabs.tabs[0];
		var folderDisplay = folderTab.folderDisplay;
		folderDisplay.selectMessageComingUp();
		tabmail.switchToTab(folderTab);
		if (folderDisplay.displayedFolder != folder
				|| folderDisplay.view.isVirtual) {
			// Force select the folder
			folderDisplay.show(folder);
			gFolderTreeView.selectFolder(folder, true);
		}
		// Force select the message
		// Pour l'instant désactivé, car bug bloquant l'affichage des messages.
		if (aMessage) {
			folderplus.log("call folderDisplay.selectMessage" + aMessage.messageId);
			var folderDB = MailUtils.getFolderForURI(folder.URI, false); 
			var message = folderDB.msgDatabase.getMsgHdrForMessageID(aMessage.messageId);
			if (message) {
				folderDisplay.selectMessage(message);	
			}
		}
		/* cas de test
		aller à dossier dans virtual folder
		aller à dossier dans onglet
		aller à dossier si pas de conversation
		aller à conversation sans conversation.
		*/
	},

	/**
	 * Move all selected messages to the first determined conversation.
	 */
	moveToThreadFolder : function() {
		var aMsgHdr = gFolderDisplay.selectedMessage;
		//folderplus.log("moveToThreadFolder messageKey = " + aMsgHdr.messageKey);
		function callback(aFolderURI){
			/* Comme l'exec du callback est asynchrone (du lancement de la commande)
			 * si utilisation du bouton droit, le message qui a reçu le bouton droit
			 * peut être different du message courant quand le callback est executé.
			 */
			var aMsgHdr = gFolderDisplay.selectedMessage;
			//folderplus.log("moveToThreadFolder.callback" + aFolderURI + "," + aMsgHdr.messageKey);
			var folder = MailUtils.getFolderForURI(aFolderURI);
			// use MsgMoveMessage to set "move again"
			MsgMoveMessage(folder);
		};
		folderplus.conv._getFolder(aMsgHdr, callback, Gloda, folderplus.callbackUI);
	},
	
	/**
	 * Move all selected messages to the first determined conversation.
	 */
	moveToThreadFolderAndUnread : function() {
		var aMsgHdr = gFolderDisplay.selectedMessage;
		//folderplus.log("moveToThreadFolder messageKey = " + aMsgHdr.messageKey);
		function callback(aFolderURI){
			/* Comme l'exec du callback est asynchrone (du lancement de la commande)
			 * si utilisation du bouton droit, le message qui a reçu le bouton droit
			 * peut être different du message courant quand le callback est executé.
			 */
			var aMsgHdr = gFolderDisplay.selectedMessage;
			//folderplus.log("moveToThreadFolder.callback" + aFolderURI + "," + aMsgHdr.messageKey);
			var folder = MailUtils.getFolderForURI(aFolderURI);
			
			var headers = Components.classes["@mozilla.org/array;1"]
                          .createInstance(Components.interfaces.nsIMutableArray);
			headers.appendElement(aMsgHdr, false);
			aMsgHdr.folder.markMessagesRead(headers, false);

			// use MsgMoveMessage to set "move again"
			MsgMoveMessage(folder);
		};
		folderplus.conv._getFolder(aMsgHdr, callback, Gloda, folderplus.callbackUI);
	},
	
	/**
  	 * 
	 */
	moveAndGoToThreadFolder : function() {
		/** Bug : le message n'est pas sélectionné après le déplacement. Peut-être car l'appel
		 * selectMessage est fait trop tôt.
		 */
		//folderplus.log("folderDisplay.moveAndGoToThreadFolder");
		var aMsgHdr = gFolderDisplay.selectedMessage;
		folderplus.log("message=" + aMsgHdr.messageId);
		function callback(aFolderURI){
			//folderplus.log("moveToThreadFolder.callback to " + aFolderURI);
			var folder = MailUtils.getFolderForURI(aFolderURI);
			// use MsgMoveMessage to set "move again"
			MsgMoveMessage(folder);
			folderplus._GoToFolder(folder, aMsgHdr);
		};
		folderplus.conv._getFolder(aMsgHdr, callback, Gloda, folderplus.callbackUI);
	},


	// ============================================================================================================
	//          Update UI (menus, labels, buttons)
	// ============================================================================================================
	
	
	
	/**
	 * Update all menu labels about folder (not conversation) (go to folder, etc).
	 * internal function, not call from UI.
	 */
	_updateAllFolderMenus : function (folderName) {
		folderplus.log("_updateAllFolderMenus");
		var bundle = document.getElementById("folderplus-strings");
		var aLabel = bundle.getFormattedString("folderplus.GoToFolder",[ folderName ], 1);
		
		document.getElementById("folderplusGoToFolderMailContext").label = aLabel;
		document.getElementById("folderplusGoToFolderGoMenu").label = aLabel;
		document.getElementById("folderplusAppmenuGoToFolder").label = aLabel;
	},
	
	/**
	 * Update all menu labels about conversation (not folder) (go to conversation, etc).
	 * internal function, not call from UI.
	 */
	_updateAllCoversationMenus : function (folderName) {
		folderplus.log("_updateAllCoversationMenus " + (folderName == null ? "null" : folderName == "" ? "vide" : folderName == "?" ? "erreur" : folderName.substr(0,4)));
		var bundle = document.getElementById("folderplus-strings");
		var aLabel     = bundle.getFormattedString("folderplusMoveToConversation", [ folderName ], 1);
		var aLabelMenu = bundle.getFormattedString("folderplusMoveToConversationMenu", [ folderName ], 1);
		
		document.getElementById("folderplusMoveToConversationFolder").label = aLabelMenu;
		document.getElementById("folderplusGoToConversation").label = aLabel;
		document.getElementById("folderplusGoToConversationGoMenu").label = aLabel;
		document.getElementById("folderplusAppmenuGoToConversation").label = aLabel;
		document.getElementById("folderplusMoveToConversationFolderMessageMenu").label = aLabelMenu;
		document.getElementById("folderplusAppmenuMoveToConversationFolder").label = aLabelMenu;
	},

	/**
	 * @param String : a folder uri, null => current folder, "error" => "?", "" => searching.
	 */
	callbackMessageHeader : function(aFolderURI){
		var iconType = "disabled";
		var label = "";
		//folderplus.log("updateMessageHeader.callback");
		if (aFolderURI == "error") {
			label = "?";
			iconType = "disabled";
		} else if (aFolderURI == "") {
			label = "";
			iconType = "load";
		} else if (aFolderURI == null) {
			var aMsgHdr = gFolderDisplay.selectedMessage;
			var currentFolder = gFolderTreeView.getFolderForMsgHdr(aMsgHdr);
			label = currentFolder.prettyName;
			iconType = "folder";
		} else {				
			// get the msg folder we're moving messages into			
			var destMsgFolder = MailUtils.getFolderForURI(aFolderURI);
			var destFolderName = destMsgFolder.prettyName;
			label = destFolderName;
			iconType = "conversation";
		}
		document.getElementById("folderplusexpandedconversationBox").value = label;
		document.getElementById("folderplusexpandedconversationBox").tooltiptext = "tooltips";
		document.getElementById("folderplusexpandedconversationicon").setAttribute("type", iconType);
		var compactHeaderHeader = document.getElementById("folderplusConversationHeaderCompactHeader");
		if (compactHeaderHeader) {
			compactHeaderHeader.value = label;
			document.getElementById("expandedconversationiconCompactHeader").setAttribute("type", iconType);
		}
	},

	/**
	 * @param String : a folder uri, null => current folder, "error" => "?", "" => searching.
	 */
	callbackContextMenu : function(aFolderURI){
		//folderplus.log("fillMailContextMenu.callback");
		var label = "";
		if (aFolderURI == null) {
			label = ".";			  
		} else if (aFolderURI == "") {
			label = "";
		} else if (aFolderURI == "error") {
			//folderplus.log("fillMailContextMenu.callback:erreur");
			label = "?";
		} else {
			// get the msg folder we're moving messages into
			var destMsgFolder = MailUtils.getFolderForURI(aFolderURI);
			var folderName = destMsgFolder.prettyName;
			label = folderName;
		}
		folderplus._updateAllCoversationMenus(label);
	},
	
	callbackUI : function(aFolderURI){
		folderplus.callbackMessageHeader(aFolderURI);
		folderplus.callbackContextMenu(aFolderURI);
	},

	/**
	 * Launch a search and update header message.
	 */
	updateMessageHeader : function () {
		var aMsgHdr = gFolderDisplay.selectedMessage;
		folderplus.conv._getFolder(aMsgHdr, null, Gloda, folderplus.callbackUI);
	},

	/**
	 * set all menus (menu bar, mail context menu and application menu) for folder and conversation.
	 * Async method :-/ First call a globa search to get a gloda message from 
	 * aMsgHdr then call a second gloda search to find all messages from the 
	 * conversation.
	 */
	fillMailContextMenu : function(event) {
		folderplus.log("fillMailContextMenu");

		var aMsgHdr = gFolderDisplay.selectedMessage;
		if (aMsgHdr == null) {
			this._updateAllFolderMenus("?");
			this._updateAllCoversationMenus("?");
			return;
		}
		// Update lables menus which talk about Folder (and not conversation)
		var folderName = aMsgHdr.folder.prettyName;
		folderplus._updateAllFolderMenus(folderName);
		folderplus.conv._getFolder(aMsgHdr, null, Gloda, folderplus.callbackUI);
	},
	
	
	// ============================================================================================================
	//           Initialisatoin, Installation, log                                                                 
	// ============================================================================================================
	
	
	init : function() {
		folderplus._console = Components.classes["@mozilla.org/consoleservice;1"].
							getService(Components.interfaces.nsIConsoleService);
		var prefs = Components.classes["@mozilla.org/preferences-service;1"]
							.getService(Components.interfaces.nsIPrefService);
		this._prefs = prefs.getBranch("extensions.folderplus.");
		
		folderplus.log("init");
		
		if (!this._prefs.getBoolPref("firstRunDone")) {
			this._prefs.setBoolPref("firstRunDone", true);
			this._installButton("header-view-toolbar", "folderplusHdrConversationButton");
		}

		gMessageListeners.push({
			onStartHeaders: function () {},
			onEndHeaders: function() {
				folderplus.updateMessageHeader();  
			},
			onEndAttachments: function () {},
		});
		
		//@ test vérifier qu'au redémarrage, la blackList est toujours prise en compte
		folderplus.options.readBlackList();
		
		/*
		 * enregistrement service pour gérer les changements de dossiers.
		 */
		var notificationService = Components.classes["@mozilla.org/messenger/msgnotificationservice;1"]
				.getService(Components.interfaces.nsIMsgFolderNotificationService);

		notificationService.addListener(folderplus.folderListener,
				notificationService.folderRenamed
				| notificationService.folderDeleted
				| notificationService.folderMoveCopyCompleted);		
				
        var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                                .getService(Components.interfaces.nsIPrefService);
		var searchlevel = prefService.getIntPref("extensions.folderplus.searchlevel");
		folderplus.log("initial search level = " + searchlevel);
		folderplus.conv.searchLevel = searchlevel;

		var searchPrefixe = prefService.getCharPref("extensions.folderplus.searchPrefixe");
        folderplus.conv.searchPrefixe = searchPrefixe;
		folderplus.log("initial search prefixe = " + searchPrefixe);
	},
	
	
	log : function (aMessage) {
		var logLevel = this._prefs.getCharPref("logLevel");
		if (logLevel == "debug") {
			this._console.logStringMessage("folderplus," + aMessage);
		}
	},
	
	_prefs : null,
	_console : null,	
	
	/**
	 * Installs the toolbar button with the given ID into the given
	 * toolbar, if it is not already present in the document.
	 *
	 * @param {string} toolbarId The ID of the toolbar to install to.
	 * @param {string} id The ID of the button to install.
	 * @param {string} afterId The ID of the element to insert after. @optional
	 */
	_installButton : function (toolbarId, id, afterId) {
	    if (!document.getElementById(id)) {
		var toolbar = document.getElementById(toolbarId);
	 
		// If no afterId is given, then append the item to the toolbar
		var before = null;
		if (afterId) {
		    var elem = document.getElementById(afterId);
		    if (elem && elem.parentNode == toolbar)
			before = elem.nextElementSibling;
		}
	 
		toolbar.insertItem(id, before);
		toolbar.setAttribute("currentset", toolbar.currentSet);
		document.persist(toolbar.id, "currentset");
	 
		if (toolbarId == "addon-bar")
		    toolbar.collapsed = false;
	    }
	}
};

// typeof test is usefull for xpcshell test unit
if (typeof(window)!='undefined') {
	window.addEventListener("load", function load(event){
		window.removeEventListener("load", load, false); //remove listener, no longer needed
		folderplus.init();
	}, false);
}
